package com.kehutong.payfees.service;

import com.kehutong.common.DoveClient;
import com.kehutong.common.Java8TimeUtils;
import com.kehutong.payfees.entity.record.ChargeRecord;
import com.kehutong.payfees.enums.WaterSource;
import com.kehutong.payfees.service.record.AccoutServiceImpl;
import com.kehutong.payfees.syn.CallBackNoReturn;
import com.kehutong.payfees.syn.Locks;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.connection.ThreadLocalCache;
import org.coraframework.util.Objects;

import javax.servlet.http.HttpServletRequest;

@WebService("/payfees/charge/payment")
public class ChargePaymentServiceImpl {

    static final Logger logger = LoggerFactory.getLogger(ChargePaymentServiceImpl.class);

    @Inject
    private JdbcSession jdbcSession;
    @Inject
    private AccoutServiceImpl accoutService;
    @Inject
    private ChargeBillServiceImpl chargeBillService;
    @Inject
    private ChargeTemporaryServiceImpl chargeTemporaryService;

    @Inject
    private DoveClient doveClient;

    /**
     * 支付回调
     */

    @ReqMapping("/callBack")
    public Object callBack(JSONObject data, HttpServletRequest req) throws Exception {
        //logger.warn("chargePaymentService-------------------jsonObject：{}", jsonObject.toJSONString());
        String companyNo = req.getHeader("companyNo");
        data.put("companyNo", companyNo);
        String attach = data.getString("attach");
        String chargeRecordId = data.getString("subOrderNo");

        ChargeRecord cr = Pool.get(ChargeRecord.class, chargeRecordId);
        if (Objects.isNull(cr)) {
            return Result.error(0, "暂未获取到流水信息");
        }

        CallBackNoReturn called = () -> {
            if (!cr.isResult()) {

                // 付款人openid
                final String openid = data.getString("openid");

                String transactionId = data.getString("transaction_id");

                JSONObject unionIdResult = doveClient.post("/kht-bin/wechat/getPaidUnionId", http -> {
                    http.addParam("appId",data.getString("appid"));
                    http.addParam("openid",data.getString("openid"));
                    http.addParam("transactionId",transactionId);
                    http.addParam("mch_id",data.getString("mch_id"));
                    http.addParam("out_trade_no",data.getString("mch_id"));
                });
                int code = unionIdResult.getIntValue("code");
                if (code == 200) {
                    String unionId = unionIdResult.getString("data");
                    if (Objects.nonEmpty(unionId)) {
                        JSONObject accountResult = doveClient.post("/auth/account/service/getAccount", (http) -> {
                            JSONObject body = new JSONObject();
                            body.put("unionId", unionId);
                            http.setBody(body.toJSONString());
                        });
                        if (accountResult.getIntValue("code") != 200) {
                            logger.error("ChargePaymentServiceImpl.callBack 获取不到账号信息");
                        }
                        JSONObject account = accountResult.getJSONObject("data");
                        if (Objects.nonEmpty(account)) {
                            cr.setMbrCode(account.getString("id"));
                            cr.setMbrName(account.getString("nickName"));
                            cr.setMobile(account.getString("mobile"));
                            cr.setAvatar(account.getString("avatar"));
                        }
                    }
                }

                cr.setExChangeCode(transactionId.trim());
                cr.setBankType(data.getString("bank_type"));
                cr.setOpenid(openid);
                cr.setTransactionId(transactionId);
                cr.setChargeTime(Java8TimeUtils.parseFromTimeEnd(data.getString("time_end")));
                cr.setResult(true);
                cr.setRemark(String.format("微信交易流水号：%s", transactionId));
                /*cr.setMchId(data.getString("mch_id"));
                cr.setSubMchId(data.getString("sub_mch_id"));
                cr.setSubmchName(data.getString("sub_mch_name"));*/
                jdbcSession.updateById(cr);



                // 支付通知成功后 根据bizType执行对应逻辑
                doBizAfterNotice(data.getString("companyNo"), cr, attach);
            }
        };

        Locks.exeSyn(cr.getId(), called);

        return Result.success();
    }

    private void doBizAfterNotice(String companyNo, ChargeRecord cr, String attch) throws Exception {
        if (cr.getBizType() == WaterSource.CHONGZHI) {
            // 向房屋充值
            accoutService.doChargeToHouse(cr);
        } else if (cr.getBizType() == WaterSource.WUYEFEI) {
            // 直接支付给物业
            accoutService.doPayWuYe(cr);
            // 根据已付款记录处理 缴费任务
            chargeBillService.handleBillByPaidChargeRecord(companyNo, cr, attch);
        } else if (cr.getBizType() == WaterSource.TEMPORARY) {
            // 直接支付给物业
            accoutService.doPayWuYe(cr);
            // 发送通知
            chargeTemporaryService.handlePaidChargeRecord(cr, attch);
        } else if (cr.getBizType() == WaterSource.SUNDRY) {
            // 直接支付给物业
            accoutService.doPayWuYe(cr);
            // 发送通知
            chargeTemporaryService.handlePaidChargeRecordByRoleId(cr, attch);
        } else {
            // ...more biz type
            logger.trace("ChargeRecord doBiz failed: {}", cr);
            throw new RuntimeException();
        }
    }
}